package com.kuqi.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.kuqi.blog.dao.pojo.SysUser;
import com.kuqi.blog.service.LoginService;
import com.kuqi.blog.service.SysUserService;
import com.kuqi.blog.util.JWTUtils;
import com.kuqi.blog.vo.ErrorCode;
import com.kuqi.blog.vo.Result;
import com.kuqi.blog.vo.params.LoginParams;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author:kuqi
 * @createTime:2021/12/13 11:05
 * @description:
 */
@Service
@Transactional //业务逻辑层事务注解
public class LoginServerImpl implements LoginService {

    //加密盐用于加密
    @Value("${password.slat}")
    private String slat;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Override
    public Result login(LoginParams loginParams) {
        /**
         * 登录接口逻辑层
         * 1.检查参数是否合法
         * 2.根据用户名和密码去user表中查询，是否存在
         * 3.如果不存在，登录失败
         * 4.如果存在，使用jwt生成token，返回给前端
         * 5.token放入redis当中，token:信息 设置过期时间
         * 登录认证的时候，先认证token字符串是否合法，去redis认证是否存在
         */

        //1.检测参数是否合法
        String account = loginParams.getAccount();
        String password = loginParams.getPassword();
        //检测账号密码是否为空
        if (StringUtils.isBlank(account)||StringUtils.isBlank(password)){
            //返回错误码，和错误信息
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(),ErrorCode.PARAMS_ERROR.getMsg());
        }


        //2.密码的加盐处理
        String pwd = DigestUtils.md5Hex(password+slat);
        //调用用户逻辑层，查询用户信息
        SysUser sysUser = sysUserService.findUser(account,pwd);


        //3.检查用户是否存在，不存在
        if (sysUser == null){
            return Result.fail(ErrorCode.ACCOUNT_PWD_NOT_EXIST.getCode(), ErrorCode.ACCOUNT_PWD_NOT_EXIST.getMsg());
        }

        //4.如果存在，使用jwt生成token
        String token = JWTUtils.createToken(sysUser.getId());

        //5.将令牌存入redis中，并设置其过期时间
        redisTemplate.opsForValue().set("TOKEN_"+token, JSON.toJSONString(sysUser),100, TimeUnit.DAYS);

        return Result.success(token);
    }

    @Override
    public Result logout(String token) {
        //后端直接删除redis中的token
        redisTemplate.delete("TOKEN_"+token);
        return Result.success(null);
    }

    @Override
    public Result register(LoginParams loginParams) {
        /**
         * 1.判断参数是否合法
         * 2.判断账户是否存在，存在返回账户已经被注册
         * 3.如果不存在，注册用户
         * 4.生成token
         * 5.存入redis并返回
         * 6.注意加上事务，一旦中间的任何过程出现问题，注册的用户需要回滚
         */
        String account = loginParams.getAccount();
        String password = loginParams.getPassword();
        String nickname = loginParams.getNickname();
        //判断是否合法
        if (StringUtils.isBlank(account)
                ||StringUtils.isBlank(password)
                ||StringUtils.isBlank(nickname)){
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(),ErrorCode.PARAMS_ERROR.getMsg());
        }
        //调用用户的业务层查询注册的用户是否存在
        SysUser sysUser = this.sysUserService.findUserByAccount(account);
        //判断账号是否存在
        if (sysUser != null){
            return Result.fail((ErrorCode.ACCOUNT_EXIST.getCode()),ErrorCode.ACCOUNT_EXIST.getMsg());
        }

        sysUser = new SysUser();
        sysUser.setNickname(nickname);
        sysUser.setAccount(account);
        sysUser.setPassword(password);
        sysUser.setCreateDate(System.currentTimeMillis());
        sysUser.setLastLogin(System.currentTimeMillis());
        sysUser.setAvatar("1");
        sysUser.setAdmin(1);
        sysUser.setDeleted(0);
        sysUser.setSalt("");
        sysUser.setStatus("");
        sysUser.setEmail("");
        //调用user业务层，将注册的新用户存储起来
        this.sysUserService.save(sysUser);

        //token,生成令牌
        String token = JWTUtils.createToken(sysUser.getId());

        //设置登录缓存，以及其token过期时间
        redisTemplate.opsForValue().set("TOKEN_"+token,JSON.toJSONString(sysUser),1,TimeUnit.DAYS);
        return Result.success(token);
    }

}
